delete
運算子delete
會回傳 false
,但語法本身仍可以被接受。錯誤類型:
TypeError: Cannot delete property 'prototype' of function Object() { [native code] }
使用前:
console.log( delete Object.prototype ); // false
使用後:
"use strict";
console.log( delete Object.prototype ); // TypeError: Cannot delete property 'prototype' of function Object() { [native code] }
eval
或 arguments
作為變數名稱eval
和 arguments
是 JavaScript 的關鍵字,各自另有用途,拿來作變數名稱容易導致非預期的結果。錯誤類型:
SyntaxError: Unexpected eval or arguments in strict mode
使用前:
function myFunc(){
return arguments;
}
var arguments = 1500;
console.log(arguments); // 1500
console.log(myFunc(1, 2, 3)); // Arguments Object [1, 2, 3]
使用後:
"use strict";
function myFunc(){
return arguments;
}
var arguments = 1500; // SyntaxError: Unexpected eval or arguments in strict mode
console.log(arguments);
console.log(myFunc(1, 2, 3));
interface
、public
、private
、package
等,在其他程式語言都是很重要也很普遍的關鍵字。錯誤類型:
TypeError: Cannot assign to read only property 'articleTarget' of object '#<Object>'
使用前:
var public = 1500;
console.log(public); // 1500
使用後:
"use strict";
var public = 1500; // SyntaxError: Unexpected strict mode reserved word
console.log(public);
eval()
宣告的變數或函數,不能在該 Scope 被語法呼叫使用eval()
宣告的時候拋錯,而是後續想使用的時候拋錯,而且拋出的錯誤類型是 ReferenceError
。eval()
內自己宣告自己使用也沒有問題,後續想用語法去呼叫使用才會拋錯。eval()
所執行的語法會自成一個暫時的 Scope,在裡面宣告的變數或函數都只屬於這個 Scope。ReferenceError
類型的錯誤。錯誤類型:
ReferenceError: x is not defined
使用前(用於變數):
eval("var x = 123");
console.log(x); // 123
使用後(用於變數):
"use strict";
eval("var x = 123");
console.log(x); // ReferenceError: x is not defined
嚴謹模式下,在 eval()
內自己宣告自己使用並沒有問題:
"use strict";
var ret = 0;
eval("var n1 = 3, n2 = 6; ret = n1 + n2;");
console.log(ret); // 9
console.log(n1); // ReferenceError: n1 is not defined
使用前(用於函數):
eval("function myFunc(){ var x = 123; console.log(x); } myFunc();");
myFunc();
123
123
使用後(用於函數):
"use strict";
eval("function myFunc(){ var x = 123; console.log(x); } myFunc();");
myFunc();
123
ReferenceError: myFunc is not defined
with
語法with
語法。錯誤類型:
SyntaxError: Strict mode code may not include a with statement
使用前:
var x, y;
with (Math){
x = cos(3 * PI) + sin(LN10);
y = tan(14 * E);
};
console.log(x); // -0.2560196630425069
console.log(y); // 0.37279230719931067
使用後:
"use strict";
var x, y;
with (Math){ // SyntaxError: Strict mode code may not include a with statement
x = cos(3 * PI) + sin(LN10);
y = tan(14 * E);
};
console.log(x);
console.log(y);
this
代表的物件不一樣this
,指的是 Global Object。this
,變成 undefined
。使用前:
function myFunc(){
console.log(this === window); // true
}
myFunc();
使用後:
"use strict";
function myFunc(){
console.log(this === window); // false (`this` is `undefined`)
}
myFunc();
(Source: 網路)
嚴謹模式下增加了很多規範,目的是讓程式更安全。
不過也不是盡善盡美,還是有遺珠。
"use strict";
var x = 10;
var x = 20;
console.log(x); // 20
這部分會建議使用前面文章介紹過的 let
或 const
來取代 var
,就可以限制變數重複宣告。
嚴謹模式的使用情境相信還有很多,無法在幾篇文章的篇幅內全數囊括。但希望透過這三篇文章的介紹,能對嚴謹模式有一定深度的了解。
當專案規模越來越大,嚴謹的開發模式和程式撰寫方式才能讓專案更容易被多人維護,使用嚴謹模式是個必然的趨勢。
事實上可以注意到,著名的 JavaScript 編譯器 Babel 在將新版 ECMAScript 轉譯成 ES5 時,在你還沒打任何程式碼之前,ES5 的那一欄已經預設好一行程式,就是 use strict
!
(Source: Babel REPL)